package com.example.mqtt.thread;

import com.example.mqtt.cache.HistoryJsonCache;
import com.example.mqtt.entity.properties.MQTTProperties;
import com.example.mqtt.service.FakeDataService;
import com.example.mqtt.service.RowingService;
import org.springframework.stereotype.Component;

import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Component
public class SchedulePool {
    private ScheduleTrainData dataTask;
    private ScheduleJointsDataGroupOne scheduleJointsData;
    private ScheduleJointsDataGroupTwo scheduleJointsDataTwo;
    private ScheduleJointsDataGroupThree scheduleJointsDataThree;
    private ScheduleJointsDataGroupFour scheduleJointsFour;
    private ScheduleEnvStats envStats;
    private ScheduleEnvVelocity envVelocity;


    private final MQTTProperties mqttProperties;
    private final RowingService rowingService;
    private final FakeDataService fakeDataService;

    public SchedulePool(MQTTProperties mqttProperties, RowingService rowingService, FakeDataService fakeDataService) {
        this.mqttProperties = mqttProperties;
        this.rowingService = rowingService;
        this.fakeDataService = fakeDataService;
    }

    private Map<String, ScheduledThreadPoolExecutor> userSchedulers = new ConcurrentHashMap<>();


    private ScheduledThreadPoolExecutor getSchedulerForUser(String rowingId) {
        return userSchedulers.computeIfAbsent(rowingId, k -> new ScheduledThreadPoolExecutor(5));
    }

    public void scheduleForUser(String rowingId,boolean isRealData,boolean isEnv_stats_velocity_data,boolean isJointsData) {
        try {
            HistoryJsonCache.build();
            ScheduledThreadPoolExecutor scheduler = getSchedulerForUser(rowingId);
            if (isRealData) {
                dataTask = new ScheduleTrainData(mqttProperties, rowingService);
                dataTask.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(dataTask, 0, 100, TimeUnit.MILLISECONDS);
            }

            if (isEnv_stats_velocity_data) {
                envStats = new ScheduleEnvStats(mqttProperties, rowingService);
                envStats.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(envStats, 0, 1000, TimeUnit.MILLISECONDS);

                envVelocity = new ScheduleEnvVelocity(mqttProperties, rowingService);
                envVelocity.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(envVelocity, 0, 10000, TimeUnit.MILLISECONDS);
            }


            if (isJointsData) {
                scheduleJointsData = new ScheduleJointsDataGroupOne(mqttProperties, rowingService, fakeDataService);
                scheduleJointsData.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(scheduleJointsData, 0, 100, TimeUnit.MILLISECONDS);

                scheduleJointsDataTwo = new ScheduleJointsDataGroupTwo(mqttProperties, rowingService, fakeDataService);
                scheduleJointsDataTwo.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(scheduleJointsDataTwo, 0, 100, TimeUnit.MILLISECONDS);

                scheduleJointsDataThree = new ScheduleJointsDataGroupThree(mqttProperties, rowingService, fakeDataService);
                scheduleJointsDataThree.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(scheduleJointsDataThree, 0, 100, TimeUnit.MILLISECONDS);

                scheduleJointsFour = new ScheduleJointsDataGroupFour(mqttProperties, rowingService, fakeDataService);
                scheduleJointsFour.setRowingId(rowingId);
                scheduler.scheduleAtFixedRate(scheduleJointsFour, 0, 100, TimeUnit.MILLISECONDS);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void stopScheduleForUser(String rowingId) {
        ScheduledThreadPoolExecutor scheduler = userSchedulers.remove(rowingId);
        if (scheduler != null) {
            scheduler.shutdown();
        }
    }

    //停掉所有线程
    public void stopAllScheduleTaskAndClear() {
        for (ScheduledThreadPoolExecutor scheduler : userSchedulers.values()) {
            scheduler.shutdown();
        }
        userSchedulers.clear();
    }


    /**
     * 检查指定用户的调度器中是否有正在运行的任务
     *
     * @param rowingId 用户ID
     * @return 如果有任务正在运行或等待执行，则返回 false；否则返回 true
     */
    public boolean isIdleScheduleTask(String rowingId) {
        ScheduledThreadPoolExecutor scheduler = userSchedulers.get(rowingId);
        if (scheduler == null) {
            return true;
        }
        int activeCount = scheduler.getActiveCount();
        if (activeCount > 0) {
            return false;
        }
        // 检查任务队列中的任务数量
        BlockingQueue<Runnable> queue = scheduler.getQueue();
        return queue.isEmpty();
    }

    public void stopAllScheduleTask() {
        for (ScheduledThreadPoolExecutor scheduler : userSchedulers.values()) {
            scheduler.shutdown();
        }
        userSchedulers.clear();
    }
}
